package org.jugile.restapi.domain;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jugile.restapi.Match;
import org.jugile.restapi.common.*;
import org.jugile.util.Buffer;
import org.jugile.util.Node;

public class Api extends ApiBase implements org.jugile.util.IDO {

	public Match match2(String uri, String method, Map params) {
		// check types 
		Type type = matchTypes(uri);
		if (type != null) {
			uri = uri.substring(0, uri.length() - type.getSuffix().length());
		} else {
			type = getDefaultType();
		}
		//print("uri: " + uri);

		if (uri.endsWith("/")) uri = uri.substring(0, uri.length()-1);
		if (uri.startsWith("/")) uri = uri.substring(1);
		String p[] = uri.split("/");
		//print("uri: " + uri + "  len: "+ p.length);
		Match m = new Match(p,method,type.getName());
		m.setParams(params);
		for (PathItem pi : getPathItems().sort("id")) {
			if (pi.match(m, 0)) return m;
		}
		return null;
	}
	
	public String urlResolve(String name) { 
		return urlResolve(name,"fi","");
	}
	public String urlResolve(String name,String lang) { 
		return urlResolve(name,lang,"");
	}
	public String urlResolve(String name, String lang, String varsStr) {
		// parse vars
		if (empty(varsStr)) return urlResolve(name,lang,(Map)null);
		Map<String,String> vars = new HashMap<String,String>();
		for (String expr : varsStr.split(" ")) {
			if (!empty(expr)) {
				String a[] = expr.split("=");
				if (a.length == 2) {
					vars.put(a[0], a[1]);
				}
			}
		}
		return urlResolve(name,lang,vars);
	}	
	public String urlResolve(String name, String lang, Map vars) {
		PathItem pi = getAllPathItems().byMatchName(name).first("id");
		if (pi != null) return pi.getFullPath(lang, vars);
		return "---";
	}
	
	private Type matchTypes(String uri) {
		for (Type t : getTypes()) {
			if (!empty(t.getSuffix()))
				if (uri.endsWith(t.getSuffix())) return t; 
		}
		return null;
	}
	
	public Type createType() {
		return d().createType().setApi(this);
	}
	public Type createType(String name, String mimetype) {
		return createType().setName(name).setSuffix("."+name).setMimetype(mimetype);
	}
	public Type getType(String name) {
		return getTypes().byName(name).unique();
	}
	
	public PathItemCollection getAllPathItems() {
		PathItemCollection pic = new PathItemCollection();
		for (PathItem pi : getPathItems()) {
			pic.add(pi.getAllPathItems());
		}
		return pic;
	}

	public PathItem createPathItem() {
		return d().createPathItem().setType(PathItemType.PATH).setApi(this);
	}
	
	public void parse(Node n) {
		for (Node tn : n.list("type")) createType().parse(tn);
		for (Node pn : n.list("path")) createPathItem().parse(pn);
	}
	
	public Node toXml() {
		Node n = new Node("api");
		for (Type v : getTypes().sort("id")) n.add(v.toXml());
		for (PathItem v : getPathItems().sort("id")) n.add(v.toXml());
		return n;
	}

	public void dump(Buffer buf, String lang) {
		buf.ln("API " + getName() + " lang: " + lang);
		buf.ln("------------------------------------------------");
		for (PathItem v : getPathItems().sort("id")) v.dump(buf,lang);
	}
	
}